package com.sc.socket.tcp;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketException;

/**
 * @author shuc001
 * @Date 2019-02-03 19:46
 */
public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = createSocket();

        initSocket(socket);
    }

    private static void initSocket(Socket socket) throws SocketException {
        // 设置读取超时时间为2s
        socket.setSoTimeout(2000);
        //是否复用未完全关闭的socket地址
        socket.setReuseAddress(true);
        //是否开启nagle算法,默认开启. 关闭后可以理解为允许批量ack,而不是对于每个数据包都需要ack
        socket.setTcpNoDelay(false);
        //长时间无响应时发送确认数据,默认2h
        socket.setKeepAlive(true);

        //表示对于close操作如何处理
        //1. false,0 默认情况,关闭时立即返回,底层接管缓冲区,如果没有发送完,则继续
        //2. true,0 关闭时立即返回,缓冲区数据抛弃,发送RST到对方,无需等待2MSL
        //3.  true,xx 最长阻塞200ms,然后按照2处理
        socket.setSoLinger(true,200);

        //是否让业务层接收到紧急数据,默认关闭,建议关闭 可以调用socket.sendUrgentData(1)发送参数的后八位
        socket.setOOBInline(false);

        //设置缓冲区大小
        socket.setReceiveBufferSize(64*1024*1024);
        socket.setSendBufferSize(64*1024*1024);


        //设置连接时间,延迟,带宽对于socket性能评估的权重,如更关心延迟,则可以调高第二个参数
        socket.setPerformancePreferences(1,1,1);
    }

    private static Socket createSocket() throws IOException {
        //相当于无参构造函数
        Socket socket = new Socket(Proxy.NO_PROXY);

        //具有http代理的构造
        Proxy proxy = new Proxy(Proxy.Type.HTTP,
                new InetSocketAddress(InetAddress.getByName("www.baidu.com"),8080));
        socket = new Socket(proxy);

        //直连模式
        socket = new Socket("localhost",20000);

        //指定本地端口 连接到20000端口的服务器,客户端使用20001端口
        socket = new Socket(InetAddress.getLocalHost(),2000,InetAddress.getLocalHost(),
                20001);

        //作用同上
        socket = new Socket();
        socket.bind(new InetSocketAddress(InetAddress.getLocalHost(),20001));
        socket.connect(new InetSocketAddress(InetAddress.getLocalHost(),20000));

        return socket;
    }
}
